<!--
 * @Date: 2024-09-20 17:16:40
 * @LastEditTime: 2025-07-02 19:14:27
 * @FilePath: \qiankunMonorepo\packages\realtime\src\views\syncTask\components\header\index.vue
-->
<template>
  <div class="w-full">
    <Form
      :label-col="labelCol"
      :wrapper-col="wrapperCol"
      ref="schemaFormRef"
      :model="searchData"
      layout="inline"
      labelAlign="right"
    >
      <!-- <Row :gutter="1" style="display: flex; justify-content: flex-start"> -->
      <Row :gutter="1" class="w-full">
        <Col :span="20">
          <Space :size="4">
            <!-- <create @click="showDrawerCreate" /> -->
            <create @click="showEvalDialog" />

            <!-- <create @click="showDrawerCreate" /> -->
            <!-- <Button
              @click="showLeadingIn"
              type="primary"
              v-permission="'v5-import'"
            >
              <PlusCircleOutlined />{{ $t("header.Import") }}</Button
            >
            <Button @click="exportFlow" type="primary">
              <PlusCircleOutlined />{{ $t("header.Export") }}</Button
            > -->
            <!-- <Dropdown>
            <template #overlay>
              <Menu @click="handleMenuClick">
                <Menu.Item key="1" :icon="h(PlayCircleOutlined)"
                  >启动</Menu.Item
                >
                <Menu.Item key="2" :icon="h(SyncOutlined)">运行</Menu.Item>
                <Menu.Item key="3" :icon="h(StopOutlined)">停止</Menu.Item>
                <Menu.Item key="4" :icon="h(ReloadOutlined)">重置</Menu.Item>
                <Menu.Item key="5" :icon="h(DeleteOutlined)">销毁</Menu.Item>
                <Menu.Item key="6" :icon="h(ToTopOutlined)">更新</Menu.Item>
                <Menu.Item key="7" :icon="h(DesktopOutlined)"
                  >子链路操作</Menu.Item
                >
              </Menu>
            </template>
            <Button> 批量操作 </Button>
          </Dropdown> -->
            <!-- <Button @click="showBatch">
              {{ $t("header.Bulkoperation") }}
            </Button> -->
            <!-- <Button @click="isSearchShow = !isSearchShow">
              <DownOutlined v-if="!isSearchShow" />
              <UpOutlined v-else />
              {{ $t("header.Advancedsearch") }}</Button
            > -->
            <a-input-group compact name="flowName" v-show="!isSearchShow">
              <a-select v-model:value="addonBeforeValue" style="width: 8rem">
                <a-select-option value="flowName">{{
                  $t("header.Taskname")
                }}</a-select-option>
                <a-select-option value="dsType">{{
                  $t("header.SourceDataSource")
                }}</a-select-option>
                <a-select-option value="createTime">{{
                  $t("header.Targetdatasource")
                }}</a-select-option>
                <a-select-option value="deployMode">{{
                  $t("header.Sourcedatatype")
                }}</a-select-option>
                <!-- <a-select-option value="dtType">{{
                  $t("header.Targetdatatype")
                }}</a-select-option> -->
              </a-select>
              <Input
                v-if="addonBeforeValue == 'flowName'"
                v-model:value="dynamicParams"
                :placeholder="plV"
                @keydown="handleKeyDown"
                @clear="handleClear"
                allowClear
                class="input-hover"
                style="width: 17rem"
              />
              <Select
                v-if="addonBeforeValue == 'dsType'"
                ref="select"
                v-model:value="dynamicParams"
                show-search
                :placeholder="plV"
                @clear="handleClear"
                allowClear
                style="width: 17rem"
              >
                <Select.Option
                  v-for="item in selV"
                  :key="item.label"
                  :value="item.index"
                  >{{ item.label }}</Select.Option
                >
              </Select>
              <Select
                v-if="addonBeforeValue == 'deployMode'"
                ref="select"
                v-model:value="dynamicParams"
                show-search
                :placeholder="plV"
                @clear="handleClear"
                allowClear
                style="width: 17rem"
              >
                <Select.Option :key="1" :value="1">{{
                  $t("header.Onlineeval")
                }}</Select.Option>
                <Select.Option :key="2" :value="2">{{
                  $t("header.Offlineeval")
                }}</Select.Option>
              </Select>
              <DatePicker
                v-if="addonBeforeValue == 'createTime'"
                v-model:value="dynamicParams"
                :placeholder="plV"
                @clear="handleClear"
                allowClear
                style="width: 17rem"
              />
            </a-input-group>
            <Form.Item name="flowName" v-show="!isSearchShow" v-if="0">
              <Input
                v-model:value="dynamicParams"
                :placeholder="$t('header.Enter')"
                @keydown="handleKeyDown"
                allowClear
                class="input-hover"
                style="width: 17rem"
              >
                <template #addonBefore>
                  <a-select
                    v-model:value="addonBeforeValue"
                    style="width: 7rem"
                  >
                    <a-select-option value="flowName">{{
                      $t("header.Taskname")
                    }}</a-select-option>
                    <a-select-option value="sourceDbAliasName">{{
                      $t("header.Sourcedatatype")
                    }}</a-select-option>
                    <a-select-option value="targetDbAliasName">{{
                      $t("header.Sourcedatatype")
                    }}</a-select-option>
                    <a-select-option value="dsType">{{
                      $t("header.Sourcelibrary")
                    }}</a-select-option>
                    <a-select-option value="dtType">{{
                      $t("header.Targetlibrary")
                    }}</a-select-option>
                  </a-select>
                </template>
              </Input>
            </Form.Item>
          </Space>
        </Col>
        <Col
          :span="4"
          style="text-align: right; padding-right: 30px !important"
        >
          <a-space>
            <a-popover title="">
              <template #content>
                <p>{{ $t("header.Setdefault") }}</p>
              </template>
              <a-button @click="openTableShow = true">
                <template #icon>
                  <FilterOutlined />
                </template>
              </a-button>
            </a-popover>
            <a-popover title="" placement="leftTop">
              <template #content>
                <div @mouseleave="mouseleaveFn">
                  <p>
                    <a-space
                      ><span>{{ $t("header.Autorefresh") }}</span
                      ><a-switch v-model:checked="autoRefresh"
                    /></a-space>
                  </p>
                  <div
                    v-show="autoRefresh"
                    style="
                      white-space: nowrap;
                      margin-top: 20px;
                      line-height: 30px;
                    "
                  >
                    <a-space>
                      <span>{{ $t("header.Refreshinterval") }}</span>
                      <a-input-number
                        id="inputNumber"
                        v-model:value="autoRefreshTIme"
                        :min="1"
                        :max="10000000"
                      />
                      <span>{{ $t("header.Second") }}</span>
                    </a-space>
                  </div>
                </div>
              </template>
              <a-button>
                <template #icon>
                  <SettingOutlined />
                </template>
              </a-button>
            </a-popover>
            <a-popover title="">
              <template #content>
                <p>{{ $t("header.Refresh") }}</p>
              </template>
              <a-button @click="refresh">
                <template #icon>
                  <RedoOutlined />
                </template>
              </a-button>
            </a-popover>
          </a-space>
        </Col>
      </Row>
      <Row v-if="isSearchShow" class="mt-1 mb-1 w-full">
        <Col :span="8">
          <Form.Item name="flowName">
            <Input
              v-model:value="searchData.flowName"
              :placeholder="$t('header.Entetaskname')"
              allowClear
              show-search
              class="input-hover"
            />
          </Form.Item>
        </Col>
        <Col :span="4">
          <Form.Item name="sourceDbAliasName">
            <Select
              ref="select"
              v-model:value="searchData.sourceDbAliasName"
              :placeholder="$t('header.Selectsource')"
              allowClear
              show-search
            >
              <Select.Option
                v-for="item in sourceItemIP.filterData"
                :key="item.label"
                :value="item.index"
                >{{ item.label }}</Select.Option
              >
            </Select>
          </Form.Item>
        </Col>
        <Col :span="4">
          <Form.Item name="targetDbAliasName">
            <Select
              ref="select"
              v-model:value="searchData.targetDbAliasName"
              :placeholder="$t('header.Selecttarget')"
              allowClear
              show-search
            >
              <Select.Option
                v-for="item in targeteItemIP.filterData"
                :key="item.label"
                :value="item.index"
                >{{ item.label }}</Select.Option
              >
            </Select>
          </Form.Item>
        </Col>
        <Col :span="4">
          <Form.Item name="dsType">
            <Select
              ref="select"
              v-model:value="searchData.dsType"
              :placeholder="$t('header.Selectsourcetype')"
              allowClear
              show-search
            >
              <Select.Option
                v-for="item in sourceItemForm.filterData"
                :key="item.label"
                :value="item.index"
                >{{ item.label }}</Select.Option
              >
            </Select>
          </Form.Item>
        </Col>
        <Col :span="4">
          <Form.Item name="dtType">
            <Select
              ref="select"
              v-model:value="searchData.dtType"
              :placeholder="$t('header.Selecttargettype')"
              allowClear
              show-search
            >
              <Select.Option
                v-for="item in targetItemForm.filterData"
                :key="item.label"
                :value="item.index"
                >{{ item.label }}</Select.Option
              >
            </Select>
          </Form.Item>
        </Col>
      </Row>
    </Form>
    <!-- 待删除 -->
    <!-- <Drawer
      v-model:open="createOpen().open"
      class="custom-taskDrawerWapperCreateZjl"
      root-class-name="root-class-name"
      :root-style="{ color: 'blue' }"
      style="background: rgb(241, 242, 245)"
      :title="$t('header.Createtask')"
      :destroyOnClose="true"
      placement="right"
      :zIndex="1009"
      width="100%"
      :footer-style="{ textAlign: 'right' }"
      @after-open-change="afterOpenChange"
    >
      <template #closeIcon>
        <ArrowLeftOutlined @click="createOpen().changeOpen(false)" />
      </template>
      <createTask ref="createTaskFlow" />
    </Drawer> -->
    <Drawer
      v-model:open="openTableShow"
      class="custom-taskDrawerWapperCreate"
      root-class-name="root-class-name"
      :root-style="{ color: 'blue' }"
      style="background: rgb(241, 242, 245)"
      :title="$t('header.DefaultItem')"
      :destroyOnClose="true"
      placement="right"
      :zIndex="1009"
      width="60%"
      :footer-style="{ textAlign: 'right' }"
      @after-open-change="afterOpenChangeTableShow"
      :closable="false"
      :maskClosable="false"
    >
      <template #extra>
        <CloseOutlined @click="openTableShow = false" style="color: #000" />
      </template>
      <tableShowTab ref="tableShowTabTbSh" @update:TableShowUP="TableShowUP" />
    </Drawer>

    <!-- 批量操作 -->
    <batch ref="batchRef" :show="batchInfo.batchShow" @closes="close"> </batch>

    <!-- 评估方式 -->
    <a-modal
      v-model:open="openEvalDialog"
      :footer="null"
      width="35%"
      :bodyStyle="{ padding: '32px 24px 16px 24px' }"
    >
      <div class="eval-modal-title">{{ $t("header.Selectevaltype") }}</div>
      <div class="eval-card-group">
        <div
          :class="['eval-card', { selected: selectedEvalType === 'offline' }]"
          @click="selectEvalType('offline')"
        >
          <div class="eval-card-title">{{ $t("header.Offlineeval") }}</div>
          <div class="eval-card-desc">
            {{ $t("header.Clickdownload")
            }}<span @click="downloadCollectTool" class="eval-download-link">{{
              $t("header.Download")
            }}</span
            >{{ $t("header.Downloadprogram") }}
          </div>
        </div>
        <div
          :class="['eval-card', { selected: selectedEvalType === 'online' }]"
          @click="selectEvalType('online')"
        >
          <div class="eval-card-title">{{ $t("header.Onlineeval") }}</div>
          <div class="eval-card-desc">{{ $t("header.Connectdatasource") }}</div>
        </div>
      </div>
      <div class="eval-modal-footer">
        <a-button type="primary" @click="handleEvalOk">{{
          $t("header.Confirm")
        }}</a-button>
      </div>
    </a-modal>
    <!-- 创建任务，使用 Suspense 包裹，加载时显示 loading -->
    <Suspense>
      <template #default>
        <createTask ref="createTaskRef" />
      </template>
      <template #fallback>
        <MyLoading />
      </template>
    </Suspense>
    <createOfflineTask ref="createOfflineTaskRef" />
  </div>
</template>

<script setup>
import {
  Menu,
  Alert,
  Card,
  Form,
  Icon,
  Input,
  Button,
  Tooltip,
  Select,
  Col,
  Row,
  Space,
  Dropdown,
  message,
  Drawer,
  Modal,
  notification,
  DatePicker,
} from "ant-design-vue";
import {
  DownOutlined,
  UpOutlined,
  PlusCircleOutlined,
  SearchOutlined,
  PlayCircleOutlined,
  StopOutlined,
  SyncOutlined,
  ReloadOutlined,
  DeleteOutlined,
  ToTopOutlined,
  DesktopOutlined,
  FilterOutlined,
  SettingOutlined,
  RedoOutlined,
  ArrowLeftOutlined,
  CloseOutlined,
} from "@ant-design/icons-vue";
// import {
//   // groupItemForm,
//   sourceItemForm,
//   targetItemForm,
//   sourceItemIP,
//   targeteItemIP,
// } from "./data";
import * as http from "@/api/flow/index.js";
import emiter from "@/plugins/bus.js";
// import createTask from "../../createTask/index.vue";
import tableShowTab from "./tableShowTab.vue";
import { useSelect } from "@/hooks/useSelect.js";
import { isPrevsVersion } from "@/store/modules/baseFormPrevsVersion";
import {
  ref,
  reactive,
  h,
  onMounted,
  watch,
  computed,
  watchEffect,
  defineAsyncComponent,
  nextTick,
} from "vue";
import { useDebounceFn } from "@vueuse/core";
import { useEffect } from "vue-hooks-api";
import { useRowSelectStore } from "@/store/modules/rowSelectStore";
import { useIntervalFn, rand } from "@vueuse/core";
import batch from "../dialog/batch.vue";
import { useStore } from "vuex";
import create from "./customBtn/create.vue";
// 异步引入创建任务组件，带 loading 和 error 组件
import MyLoading from "@/components/loading/loading.vue";
import MyError from "@/components/loading/error.vue";
const createTask = defineAsyncComponent({
  loader: () => import("@/views/objectCollection/createTask/index.vue"),
  loadingComponent: MyLoading,
  errorComponent: MyError,
  delay: 200,
  timeout: 10000,
});
const createOfflineTask = defineAsyncComponent({
  loader: () => import("@/views/objectCollection/createOfflineTask/index.vue"),
  loadingComponent: MyLoading,
  errorComponent: MyError,
  delay: 200,
  timeout: 10000,
});

const store = useStore();
defineOptions({
  name: "DemoTableHeader",
});
const handleKeyDown = (event) => {
  if (event.key === "Enter" || event.key === " ") {
    event.preventDefault(); // 阻止默认行为
    refresh();
    console.log("空格或 Enter 被阻止");
  }
};

const handleClear = () => {
  // 清除输入框内容时，立即触发搜索
  dynamicParams.value = "";
  searchData[addonBeforeValue.value] = undefined;
  // 清除其他搜索条件
  for (let key in searchData) {
    if (key !== addonBeforeValue.value) {
      if (key !== "taskGroup" && key !== "flowGroupId") {
        searchData[key] = undefined;
      }
    }
  }
  // 立即触发搜索
  emiter.emit("refreshFunSearch", searchData);
};
const isSearchShow = ref(false);
const leadingInRef = ref(null);
const batchRef = ref(null);

const leadingInInfo = reactive({
  leadingInShow: false,
});
const batchInfo = reactive({
  batchShow: false,
});

watch(isSearchShow, (val) => {
  console.log("val: ", val);
  if (val) {
    dynamicParams.value = "";
    addonBeforeValue.value = "flowName";
  }
  !val && (searchData.flowName = undefined);
  !val && (searchData.dsType = undefined);
  !val && (searchData.dtType = undefined);
  !val && (searchData.sourceDbAliasName = undefined);
  !val && (searchData.targetDbAliasName = undefined);
});
const loading = ref(false);
const createTaskFlow = ref(null);
const searchData = reactive({
  taskName: "",
  flowName: "",
  taskGroup: undefined,
  flowGroupId: undefined,
  dsType: undefined,
  dtType: undefined,
  sourceDbAliasName: undefined,
  targetDbAliasName: undefined,
});
const dynamicParams = ref("");
const addonBeforeValue = ref("flowName");
onMounted(() => {
  store.commit(
    "setButtonKeys",
    JSON.parse(sessionStorage.getItem("buttonKeys"))
  );
});
const debouncedUpdateSearch = useDebounceFn((val) => {
  // 当输入值为空或undefined时，清除对应的搜索条件
  if(val === '' || val === undefined) {
    searchData[addonBeforeValue.value] = undefined;
    // 清除其他搜索条件
    for (let key in searchData) {
      if (key !== addonBeforeValue.value) {
        if (key !== "taskGroup" && key !== "flowGroupId") {
          searchData[key] = undefined;
        }
      }
    }
    return;
  }
  searchData[addonBeforeValue.value] = val;
  for (let key in searchData) {
    if (key !== addonBeforeValue.value) {
      if (key !== "taskGroup" && key !== "flowGroupId") {
        searchData[key] = undefined;
      }
    }
  }
}, 800);

watch(() => {
  debouncedUpdateSearch(dynamicParams.value);
});
watch(addonBeforeValue, (val) => {
  let str = {
    flowName: $t("header.Entetaskname"),
    sourceDbAliasName: $t("header.Selectsource"),
    targetDbAliasName: $t("header.Selecttarget"),
    dsType: $t("header.Selectsourcetype"),
    dtType: $t("header.Selecttargettype"),
  };
  let ar = {
    flowName: [],
    sourceDbAliasName: sourceItemIP.filterData,
    targetDbAliasName: targeteItemIP.filterData,
    dsType: sourceItemForm.filterData,
    dtType: targetItemForm.filterData,
  };
  plV.value = str[addonBeforeValue.value];
  selV.value = ar[addonBeforeValue.value];
  dynamicParams.value = addonBeforeValue.value == "flowName" ? "" : undefined;
  searchData[addonBeforeValue.value] = "";
});
const labelCol = { style: { width: "0px" } };
const wrapperCol = { style: { width: "180px" } };
const loadParams = reactive({
  data: {
    userID: sessionStorage.getItem("userId"),
  },
});
// 获取源数据源下拉框
const sourceItemForm = useSelect(http.getDataBaseTypeInfo, {
  path: {
    data: "data",
    key: "dbConfId",
    value: "dbConfId",
    label: "dbConfName",
    disabled: "disabled",
  },
  immediate: true,
});
// 获取目标数据源下拉框
const targetItemForm = useSelect(http.getDataBaseTypeInfo, {
  path: {
    data: "data",
    key: "dbConfId",
    value: "dbConfId",
    label: "dbConfName",
    disabled: "disabled",
  },
  immediate: true,
});
// 获取源主机下拉框
const sourceItemIP = useSelect(http.getAllDbAliasName, {
  path: {
    data: "data",
    key: "db_alias_name",
    value: "db_alias_name",
    label: "db_alias_name",
    disabled: "disabled",
  },
  loadParams: loadParams,
  immediate: true,
});
// 获取目标数据源下拉框
const targeteItemIP = useSelect(http.getAllDbAliasName, {
  path: {
    data: "data",
    key: "db_alias_name",
    value: "db_alias_name",
    label: "db_alias_name",
    disabled: "disabled",
  },
  loadParams: loadParams,
  immediate: true,
});
const handleSearch = () => {
  emiter.emit("refresh", searchData);
};
const resetSearch = () => {};
// const handleCreate = () => {

// };
// const open = ref(false);
// const open = createOpen().open;

const afterOpenChange = (bool) => {
  console.log("open", bool);
  changePrevVerion(true, !bool);
  console.log(bool, "bool");
  if (!bool) {
    saveCustomRealFlowFlag();
  }
};

const saveCustomRealFlowFlag = async () => {};

// 打开批量
const showBatch = () => {
  const rowSelect = useRowSelectStore();
  if (rowSelect.selectedRowKeys.length == 0) {
    message.error("请选择流程");
  } else {
    batchInfo.batchShow = true;
    batchRef.value.initGroups(rowSelect.selectedRowKeys);
  }
  setTimeout(() => {
    // leadingInRef.value.initGroups()
  }, 500);
};
const exportFlow = () => {
  // let res1 = await http.saveCustomRealFlowFlag({
  //   flowString: false
  // });
  emiter.emit("exportAllFlow");
};
const close = () => {
  leadingInInfo.leadingInShow = false;
  batchInfo.batchShow = false;
  // emiter.emit("refresh");
  emiter.emit("refreshFunSearch", searchData);
  console.log("aavvadadasd");
};
const showDrawerCreate = (status = true) => {
  return;

  //详情作区分
  if (status) {
    //创建flowId
    console.log("jinlai");
    const rowSelectStore = useRowSelectStore();
    rowSelectStore.setRowSelect({ flowId: Date.now() + getrandom() });
  }

  //打开弹框方便调取关闭接口
  createOpen().changeOpen(true);
};
// TODO接收点击流程打开创建任务
emiter.on("showDrawerCreateTask", (status) => showDrawerCreate(status));
//解绑emit
import { onUnmounted } from "vue";
onUnmounted(() => {
  emiter.off("showDrawerCreateTask");
});
const getrandom = () => {
  var str = "";
  for (var i = 0; i < 5; i++) {
    // str += (Math.random() * 10).toFixed(0);
    str += (Math.random() * 3).toFixed(0);
  }
  return str;
};

const onClose = () => {
  console.log("8888888888");
  // open.value = false;
  // createOpen().changeOpen(false);
};

const handleMenuClick = () => {};
const refresh = () => {
  // emiter.emit("refresh");
  emiter.emit("refreshFunSearch", searchData);
};
const changePrevVerion = (status, isrefresh) => {
  const prevVsion = isPrevsVersion();
  prevVsion.changePrevVerion(status);
  if (isrefresh) {
    emiter.emit("refreshFunSearch", searchData);
  }
};

const debouncedRefresh = useDebounceFn(() => {
  refresh();
}, 300);
watch(
  searchData,
  (newValue, oldValue) => {
    debouncedRefresh();
  },
  {
    deep: true,
    immediate: false,
  }
);

// TODO 设置默认展示项
const openTableShow = ref(false);
const afterOpenChangeTableShow = (bool) => {
  console.log("open", bool);
  //    changePrevVerion(true, !bool);
  console.log(bool, "bool");
  if (!bool) {
    //        saveCustomRealFlowFlag();
  }
};
const TableShowUP = (bool) => {
  openTableShow.value = false;
  if (!bool) {
    //        saveCustomRealFlowFlag();
  }
};
//TODO 根据选择切换提示项
const plV = ref($t("header.Entetaskname"));
const selV = ref([]);
//TODO 自动刷新
const autoRefresh = ref(false);
const autoRefreshTIme = ref(30);
//watch(autoRefreshTIme, (val) => {
//    if (val) {
//        autoRefreshTIme.value = 1
//    }
//});
const mouseleaveFn = () => {
  interval.value = autoRefreshTIme.value * 1000;
  autoRefresh.value ? resume() : pause();
};
//TODO 实时开关
let interval = ref(1000);
const { pause, resume, isActive } = useIntervalFn(
  () => {
    refresh();
  },
  interval,
  { immediate: false }
);

const openEvalDialog = ref(false); // 控制评估Dialog显示
const selectedEvalType = ref(""); // 选中的评估方式
const createTaskRef = ref(null);
const createOfflineTaskRef = ref(null);
const showEvalDialog = () => {
  console.log("showEvalDialog");
  openEvalDialog.value = true;
  selectedEvalType.value = "";
};
const selectEvalType = (type) => {
  selectedEvalType.value = type;
};
const handleEvalOk = () => {
  if (!selectedEvalType.value) {
    message.error($t("header.Selectevaltype"));
    return;
  }
  openEvalDialog.value = false;
  if (selectedEvalType.value === "offline") {
    nextTick(() => {
      createOfflineTaskRef.value.openDrawer(false, "add");
    });
  } else {
    nextTick(() => {
      createTaskRef.value.openDrawer();
    });
  }
};

const downloadCollectTool = () => {
  // TODO: 替换为实际下载链接或逻辑
  window.open("https://your-download-link.com/collect-tool", "_blank");
};
</script>

<style scoped>
.search-wrapper {
  margin-bottom: 20px;
}

.toolbar-wrapper {
  display: flex;
  justify-content: space-between;
  margin-bottom: 20px;
}

.table-wrapper {
  margin-bottom: 20px;
}

.pager-wrapper {
  display: flex;
  justify-content: flex-end;
}
.input-hover {
  transition: width 0.3s; /* 平滑过渡效果 */
  /* width: 200px; 默认宽度 */
}

.input-hover:hover {
  /* width: 240px; 鼠标悬停时的宽度 */
}

.eval-modal-title {
  font-size: 20px;
  font-weight: bold;
  text-align: center;
  margin-bottom: 32px;
}
.eval-card-group {
  display: flex;
  gap: 32px;
  justify-content: center;
  margin-bottom: 24px;
  flex-wrap: wrap;
}
.eval-card {
  flex: 1 1 180px;
  min-width: 160px;
  max-width: 210px;
  background: #fff;
  border: 1.5px solid #e5e7eb;
  border-radius: 14px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
  padding: 28px 18px 20px 18px;
  cursor: pointer;
  text-align: center;
  transition: box-shadow 0.2s, border 0.2s, background 0.2s;
  user-select: none;
}
.eval-card:hover {
  box-shadow: 0 4px 20px 0 rgba(24, 144, 255, 0.12);
  border: 1.5px solid #91caff;
  background: #f0f7ff;
}
.eval-card.selected {
  border: 2px solid #1890ff !important;
  background: #e6f7ff;
  box-shadow: 0 4px 20px 0 rgba(24, 144, 255, 0.18);
}
.eval-card-title {
  font-size: 18px;
  font-weight: 600;
  margin-bottom: 10px;
}
.eval-card-desc {
  color: #888;
  font-size: 14px;
  line-height: 1.6;
}
.eval-modal-footer {
  text-align: right;
  margin-top: 8px;
}
.eval-download-link {
  color: #1890ff;
  cursor: pointer;
  text-decoration: underline;
  margin-right: 2px;
  font-weight: 500;
  transition: color 0.2s;
}
.eval-download-link:hover {
  color: #40a9ff;
}
@media (max-width: 600px) {
  .eval-card-group {
    flex-direction: column;
    gap: 18px;
    align-items: stretch;
  }
  .eval-card {
    max-width: 100%;
    min-width: 0;
  }
}
</style>
